using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Input.Touch;
using Perovich.GameObjects.Helpers;

#if XBOX
#else
using System.Windows;
#endif


namespace Perovich.GameObjects.Controls
{

    /// <summary>
    /// The <see cref="Button"/> class is a clickable button that displays text.
    /// </summary>
    public class Button : ClickableControl
    {
        TextLabel _txt;
        Perovich.GameObjects.Controls.Shapes.TextureRectangle _bordrect;


        /// <summary>
        /// Gets or sets the text displayed on the button.
        /// </summary>
        public string Text {
            set
            {
                _txt.Text = value;
            }
            get
            {
                return _txt.Text;
            }
        }

        /// <summary>
        /// Gets or sets the <see cref="SpriteFont"/> used to display the text.
        /// </summary>
        public SpriteFont Font
        {
            set
            {
                _txt.Font = value;
            }
            get
            {
                return _txt.Font;
            }
        }

        private Color _borderColor;

        /// <summary>
        /// Gets or sets the <see cref="Color"/> of the border of the <see cref="Button"/>
        /// </summary>
        public Color BorderColor
        {
            get
            {
                return _borderColor;
            }
            set
            {
                Color old = _borderColor;
                _borderColor = value;
                if (_borderColor != old)
                    LoadTexture();
            }
        }

        /// <summary>
        /// Gets or sets the <see cref="Thickness"/> of the border.
        /// </summary>
        public Thickness Border
        {
            get;
            set;
        }


        /// <summary>
        /// Constructs a new instance of the <see cref="Button"/> class.
        /// </summary>
        /// <param name="game"><see cref="Perovich.GameObjects.Interfaces.ICanHoldComponents"/> instance that this <see cref="DrawableComponent"/> will be constructed for.</param>
        public Button(Interfaces.ICanHoldComponents game)
            : base(game)
        {
            _borderColor = Color.White;
            Border = new Thickness();
            _bordrect = new Shapes.TextureRectangle(this);
            _bordrect.Depth = 0.5f;
            _txt = new TextLabel(this);
            Depth = 0;
            MarginChanged += new EventHandler(Button_MarginChanged);
            WidthChanged += new EventHandler(Button_WidthChanged);
            HeightChanged += new EventHandler(Button_HeightChanged);
            BackgroundColorChanged += new EventHandler(Button_BackgroundColorChanged);

            
        }

        

        void Button_BackgroundColorChanged(object sender, EventArgs e)
        {
            LoadTexture();
        }

        void Button_HeightChanged(object sender, EventArgs e)
        {
            LoadTexture();
        }

        void Button_WidthChanged(object sender, EventArgs e)
        {
            LoadTexture();
        }

        void Button_MarginChanged(object sender, EventArgs e)
        {
            _txt.Margin = this.Margin;
        }


        /// <summary>
        /// Loads the content for this <see cref="Button"/>.
        /// </summary>
        protected override void LoadContent()
        {
            Textures.Initialize(this);
            LoadTexture();
            Width = _txt.Width + (float)Border.Left + (float)Border.Right;
            Height = _txt.Height + (float)Border.Top + (float)Border.Bottom;
            base.LoadContent();
        }

        void LoadTexture()
        {
            if ((Width != 0) & (Height != 0))
            {
                _bordrect.Texture = Textures.CreateGradient((int)Width, (int)Height, BorderColor, BackgroundColor, GradientStyle.Border, GradientProgression.Linear, Border);
            }
        }
        /// <summary>
        /// Constructs a new <see cref="Button"/> instance.
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Update(GameTime gameTime)
        {
            _txt.Position = new Vector2((float)Border.Left,(float)Border.Top);
            Width = _txt.Width + (float)Border.Left + (float)Border.Right;
            Height = _txt.Height + (float)Border.Top + (float)Border.Bottom;
            _bordrect.Position = Vector2.Zero;
            _bordrect.Width = Width;
            _bordrect.Height = Height;
            base.Update(gameTime);
            
        }


        /// <summary>
        /// Allows the button to draw on its render target.
        /// </summary>
        /// <param name="gameTime">A snapshot of the game's timing values.</param>
        public override void DrawOnTargets(GameTime gameTime)
        {
            base.DrawOnTargets(gameTime);
            _txt.ForegroundColor = this.ForegroundColor;
            GraphicsDevice.SetRenderTarget(RenderTargetManager.GetRenderTarget(GraphicsDevice, Width, Height, this));
            //SBatches.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
            base.Draw(gameTime);
            //SBatches.End();
            GraphicsDevice.SetRenderTarget(null);
        }

        /// <summary>
        /// draws the button.
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Draw(GameTime gameTime)
        {
            SBatches.CurrentBatch.Draw(RenderTargetManager.GetRenderTarget(GraphicsDevice, Width, Height, this), new Rectangle((int)Position.X, (int)Position.Y, (int)Width, (int)Height), new Rectangle(0, 0, (int)Width, (int)Height), Color.White, 0, Vector2.Zero, SpriteEffects.None, Depth);
        }
    }
}
